"""
ReadMe:
1. 本程序用于统计Bug信息，生成Bug信息统计报表
2. 本程序生成Bug的PDF图表文件
    2.1项目缺陷状态信息统计
    2.2项目缺陷严重程度信息统计
    2.3项目缺陷按版本分布信息统计
    2.4项目缺陷按引入阶段分布信息统计
"""
import os
import pandas as pd
import numpy as np
import chardet
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

# 避免matplotlib中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']


# 在固定的路径下遍历文件夹，获取CSV文件名列表
def get_file_list(path):
    file_list = []
    for root, dirs, files in os.walk(path):
        for file in files:
            # 默认情况下，只读取路径下的CSV类型的文件
            if os.path.splitext(file)[1].lower() == '.csv':
                file_list.append(file)

    return file_list


# 通过地址+文件名列表，使用pandas库分别读取CSV文件内容，生成并返回一个DateFrame对象
def get_file_content(file_list):
    # 定义一个DateFrame类型的对象file_content
    file_content = pd.DataFrame()
    for file in file_list:
        # 将查询的结果合并成一个DateFrame类型的对象file_content
        file_content = pd.concat([file_content, pd.read_csv(path + file, encoding=file_encoding)], axis=0)

    return file_content


# 检测CSV文件的编码类型并返回编码类型
def check_file_encoding(file_path):
    with open(file_path, 'rb') as f:
        # 读取文件的前1024个字节作为样本进行检测
        sample = f.read(1024)
        # 使用chardet.detect方法检测文件的编码类型
        encoding_info = chardet.detect(sample)
        encoding = encoding_info.get('encoding')
        return encoding if encoding is not None else "Unknown"


def draw_pie(file_content):
    # 创建一个PdfPages对象用于写入多个图形
    pdf_pages = PdfPages('E:/工作文件/运营管理部 项目指标/Bug/Bug信息统计报表-按项目月份.pdf')
    unique_project_list = file_content.drop_duplicates(subset='项目')['项目'].to_list()
    # print(unique_project_list)
    # 针对每一个项目进行单独处理
    for project in unique_project_list:
        # 过滤后的数据，按照“状态”列的内容进行分类计数汇总
        grouped = file_content[file_content['项目'] == project].groupby('状态')['辅助列'].value_counts()
        # 按循环生成每一个饼状图
        plt.figure(figsize=(10, 10))
        plt.pie(grouped, labels=grouped.index, autopct='%1.1f%%', shadow=False, startangle=90)
        # 生成饼状图的图例
        plt.legend(loc='upper right')
        plt.title(project + '项目缺陷状态信息统计')
        pdf_pages.savefig()
        plt.close()

        # 过滤后的数据，按照“严重程度”列的内容进行分类计数汇总
        grouped = file_content[file_content['项目'] == project].groupby('严重程度')['辅助列'].value_counts()
        # 按循环生成每一个饼状图
        plt.figure(figsize=(10, 10))
        plt.pie(grouped, labels=grouped.index, autopct='%1.1f%%', shadow=False, startangle=90)
        # 生成饼状图的图例
        plt.legend(loc='upper right')
        plt.title(project + '项目缺陷严重程度信息统计')
        pdf_pages.savefig()
        plt.close()

        # bug按“发现版本”分布
        grouped = file_content[file_content['项目'] == project].groupby('发现版本')['辅助列'].value_counts()
        # print(grouped)
        # 按循环生成每一个饼状图
        plt.figure(figsize=(10, 10))
        plt.bar(x=grouped.index.get_level_values(0), height=grouped.values.flatten(), width=0.5)
        # 为每个柱子添加标签
        for i, v in enumerate(grouped.values):
            plt.text(i, v, "{:.1f}".format(v), ha='center', va='bottom', fontsize=6)
        # 生成饼状图的图例
        plt.xticks(fontsize=10, rotation=90)
        plt.xlabel('发现版本')
        plt.ylabel('bug数量')
        plt.tight_layout()
        plt.title(project + '项目缺陷按版本分布信息统计')
        pdf_pages.savefig()
        plt.close()

        # 按bug的“引入阶段”分布
        grouped = file_content[file_content['项目'] == project].groupby('引入阶段')['辅助列'].value_counts()
        # 按循环生成每一个饼状图
        plt.figure(figsize=(10, 10))
        plt.pie(grouped, labels=grouped.index, autopct='%1.1f%%', shadow=False, startangle=90)
        # 生成饼状图的图例
        plt.legend(loc='upper right')
        plt.title(project + '项目缺陷按引入阶段分布信息统计')
        pdf_pages.savefig()
        plt.close()

        # 按bug的“创建于”分布
        # 将创建于的时间格式转换为年月日
        file_content['创建于'] = pd.to_datetime(file_content['创建于']).dt.strftime('%Y-%m-%d')
        grouped = file_content[file_content['项目'] == project].groupby('创建于')['辅助列'].value_counts()
        # 按循环生成每一个饼状图
        plt.figure(figsize=(15, 10))
        plt.bar(x=grouped.index.get_level_values(0), height=grouped.values.flatten(), width=0.3)
        # 为每个柱子添加标签
        for i, v in enumerate(grouped.values):
            plt.text(i, v, "{:.1f}".format(v), ha='center', va='bottom', fontsize=6)
        plt.xticks(fontsize=10, rotation=90)
        plt.xlabel('发现日期')
        plt.ylabel('bug数量')
        plt.tight_layout()
        plt.title(project + '项目缺陷按日期分布信息统计')
        pdf_pages.savefig()
        plt.close()

    # 最后关闭PDF文件
    pdf_pages.close()


# 在项目内定义一个path路径
path = 'E:/工作文件/运营管理部 项目指标/Bug/数据/'
# path = '/Users/conan/PycharmProjects/wukong/Files/workLoad/'

# 调用get_file_list()方法获取文件名列表
file_list = get_file_list(path)

# 读取第一个文件的编码类型
file_encoding = check_file_encoding(path + file_list[0])

# 调用get_file_content()方法获取文件内容，返回DataFrame对象file_content
file_content = get_file_content(file_list)
file_content['辅助列'] = '1'

draw_pie(file_content)
